/*
|			Tablebase file operations
\*---------------------------------------------------------------------*/

#include <stdio.h>
#include "common.h"

#if !defined(H_FILEOPER)
#define H_FILEOPER

namespace Tablebases
{

	#define EGTB_MAXBLOCKSIZE 65536

	// setting path
	extern void tb_SetEndGamePath(const char* szPath);
	extern char* tb_GetEndGamePath();
	
#ifdef THREADING
	extern mythread_mutex_t	Egtb_lock;
#endif

	// database and subdatabase structures

	struct ZIPINFO {
		index_t 	extraoffset;
		index_t 	totalblocks;
		index_t *	blockindex;
	};

	#define MAX_WM			8
	#define MAX_BM			8
	#define MAX_WK			8
	#define MAX_BK			8
	#define MAX_WMRANK		7
	#define MAX_BMRANK		7
	#define MAX_COLOR		2

	// end game db header
	struct fileeheader
	{
		char tag[3];				// file type tag recognition
		unit_t checkersType;		// PDN GameType value
		unit_t compressionType;		// type of compression
	};

	struct subendgame
	{
		tbkey_t db;
		uint64_t offset;
		//dtm_t*	egt_w;
		//dtm_t*	egt_b;
		ZIPINFO zipInfo;
		index_t maxindex;
	};
	
	struct endgamekey {
		int 		id;
		const char *str;
//		index_t 	maxindex;
		FILE *		fd;
		int 		status;
	};

	extern struct endgamekey egkey[];
	extern subendgame egSubDb[MAX_WM][MAX_WK][MAX_BM][MAX_BK][MAX_WMRANK][MAX_BMRANK][MAX_COLOR];

	// subdb record
	struct subdbRec
	{
		uint8_t wm;
		uint8_t wk;
		uint8_t bm;
		uint8_t bk;
		uint8_t wmrank;
		uint8_t bmrank;
		uint8_t color;
		uint32_t offset;
		uint32_t numblocks;
		uint32_t maxindex;
	};


	extern unsigned int zipinfo_init (void);
	extern void zipinfo_done (void);
	static size_t zipinfo_memory_allocated (void);
	static size_t tb_indexmemory (void);
	mySHARED /*@NULL@*/ FILE *fd_openit (tbkey_t key);



	static index_t egtb_block_getnumber(int wm, int wk, int bm, int bk, int wmrank, int bmrank, int color, index_t idx);
	static index_t egtb_block_getsize(int wm, int wk, int bm, int bk, int wmrank, int bmrank, int color, index_t idx);
	static index_t egtb_block_getsize_zipped(int wm, int wk, int bm, int bk, int wmrank, int bmrank, int color, index_t block );
	static bool_t  egtb_block_park  (tbkey_t key, int wm, int wk, int bm, int bk, int wmrank, int bmrank, int color, index_t block);
	static bool_t  egtb_block_read(tbkey_t key, index_t len, unsigned char *buffer); 
	static bool_t  egtb_block_decode(tbkey_t key, index_t z, unsigned char *bz, index_t n, unsigned char *bp);
	static bool_t  egtb_file_beready(tbkey_t key);
	static bool_t  egtb_loadindexes(tbkey_t key);
	static bool_t fread32(FILE *f, /*@out@*/ unsigned long int *y);
	static bool_t preload_cache (tbkey_t key, int wm, int wk, int bm, int bk, int wmrank, int bmrank, int color, index_t idx);
	mySHARED bool_t get_dtm (tbkey_t key, int wm, int wk, int bm, int bk, int wmrank, int bmrank, int color, index_t idx, dtm_t *out, bool_t probe_hard_flag);
	extern bool_t egtb_get_dtm (tbkey_t k, int wm, int wk, int bm, int bk, int wmrank, int bmrank, int color, bool_t probe_hard_flag, dtm_t *dtm);
	extern unsigned int inv_wdl(unsigned w);
	extern bool_t wdl_preload_cache (tbkey_t key, int wm, int wk, int bm, int bk, int wmrank, int bmrank, int color, index_t idx);
	extern bool_t get_WDL (tbkey_t key, int wm, int wk, int bm, int bk, int wmrank, int bmrank, int color, index_t idx, unsigned int *info_out, bool_t probe_hard_flag);
	extern bool_t  egtb_get_wdl (tbkey_t k, int wm, int wk, int bm, int bk, int wmrank, int bmrank, int color, bool_t probe_hard_flag, unsigned int *wdl);

	// support for uncompressed databases possibly later
	// static index_t egtb_block_uncompressed_to_index (tbkey_t key, index_t b);

	// there is doubt, this style of packing plies is needed for checkers
	// static bool_t  egtb_block_unpack(unsigned side, index_t n, const unsigned char *bp, dtm_t *out);
	
}

#endif
